package com.wedimob.slideshare.parser.strategy;

import java.net.URI;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;

import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;

import com.google.gson.Gson;
import com.wedimob.slideshare.WriteType;
import com.wedimob.slideshare.bo.Medium;
import com.wedimob.slideshare.bo.SharedDocument;
import com.wedimob.slideshare.bo.Summary;
import com.wedimob.slideshare.parser.annotation.Factory;
import com.wedimob.slideshare.task.PoolExecutor;
import com.wedimob.slideshare.task.Task;
import com.wedimob.slideshare.task.disk.PathHelper;
import com.wedimob.slideshare.task.network.TaskMediumWriter;

public class SlideShareDocumentParser implements ShareDocumentParser {

    private Summary summary;
    private Document document;

    public SlideShareDocumentParser(Summary summary, Document document, WriteType write) {
        super();
        this.summary = summary;
        this.document = document;
    }

    private static class JSonContainer {
        public JSonSlideshare slideshow;
    }

    private static class JSonSlideshare {
        public String pin_image_url;
        public Integer total_slides;
        public String title;
        public String user_login;
    }

    private JSonContainer extractMetaData(Document doc) {
        String flashPlayer = document.html();
        int beginIdx = flashPlayer.indexOf("slideshare_object = ") + 20;
        int endIdx = flashPlayer.indexOf("; var", beginIdx);
        String flashPlayerJson = flashPlayer.substring(beginIdx, endIdx);
        Gson gson = new Gson();
        return gson.fromJson(flashPlayerJson, JSonContainer.class);
    }

    @Override
    public SharedDocument get(PoolExecutor pool, WriteType write, int timeout) {
        JSonContainer json = null;
        if (summary.getSlidenb() == null) {
            if (json == null)
                json = extractMetaData(document);

            summary.setAuthor(json.slideshow.user_login);
            Element body = document.select("body.smartling-fr").first();
            summary.setCategory(Factory.getElementAttribute(Factory.createDocument(body, document.baseUri()),
                    "li.category", null, null));
            Medium picture = new Medium("0000", Factory.buildURL(document,
                    json.slideshow.pin_image_url),
                    PathHelper.buildTmpPath(summary.getAuthor()));

            summary.setPicture(picture);

            String date = document.select("[name=slideshow_published_time]")
                    .first().attr("content");
            summary.setPublicationDate(Factory.parseCalendar(date));
            summary.setSlidenb(json.slideshow.total_slides);
            summary.setSummary(Factory.getElementAttribute(Factory.createDocument(body, document.baseUri()),
                    "p.descriptionExpanded", null, null));
            summary.setTitle(json.slideshow.title);
        }

        Integer counter = Factory.parseInteger(document.select("strong.h-view-count")
                .first().text().replace(",", ""));

        // Extract url patterns
        String imagesPatterns = Factory.getElementAttribute(document,
                "div.playerFacadeImage", "style", null);

        String nbPageStr = null;

        if (imagesPatterns == null) {
            if (json == null)
                json = extractMetaData(document);

            imagesPatterns = json.slideshow.pin_image_url;
            imagesPatterns = imagesPatterns.replace("slide-1.",
                    "slide-{PAGE}.");
            nbPageStr = "" + json.slideshow.total_slides;
        }
        imagesPatterns = imagesPatterns.replace("background-image:url('",
                "");
        imagesPatterns = imagesPatterns.replace("')", "");
        imagesPatterns = imagesPatterns
                .replace("slide-1-", "slide-{PAGE}-");

        // Extract max page number
        if (nbPageStr == null)
            nbPageStr = Factory.getElementAttribute(document, "label.goToSlideLabel",
                    null, null);
        Integer nbPages = Factory.parseInteger(nbPageStr);

        List<Medium> pictures = new ArrayList<Medium>();

        for (int i = 1; i < nbPages + 1; i++) {
            String url = new String(imagesPatterns);
            URL mediumURL = Factory.buildURL(document, url.replace("{PAGE}", "" + i));
            URI mediumURI = PathHelper.buildTmpPath(summary.getAuthor(), summary.getTitle());
            Medium picture = new Medium(Task.decFormat.format(i), mediumURL, mediumURI);
            pictures.add(picture);

            if (write != WriteType.NONE)
                pool.execAsync(new TaskMediumWriter(pool, picture, timeout));
        }

        /*
         * Element element = input.select("li.relatedContent").first();
         * 
         * element = input.select("li.moreContent").first();
         */

        SharedDocument result = new SharedDocument(summary);
        result.setNbViews(counter);
        for (Medium picture : pictures)
            result.addMedium(picture);

        return result;
    }
}
